home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 3 / Amiga Tools 3.iso / audio / deliay014 / dev / src / zxayemul.s < prev    next >
Text File  |  1994-10-18  |  11KB  |  513 lines

  1.  
  2. *********** Z80 Emul AY Player, (C) 1994 Patrik Rak - Raxoft **********
  3. ******************** Part of PlayAY distribution **********************
  4.  
  5. DEBUG    equ    0
  6. COLOROUT    equ    0
  7.  
  8.     ifne    DEBUG
  9.     bsr.w    initplayer
  10.     tst.l    d0
  11.     bne.b    error
  12.     lea    test(pc),a0
  13.     bsr.w    initsound
  14.     bsr.w    interrupt
  15.     bsr.w    endsound
  16.     bsr.w    endplayer
  17. error    rts
  18.  
  19. test    dc.b    0,1,2,3
  20.     dc.w    1000
  21.     dc.w    100
  22.     dc.w    $1234
  23.     dc.w    testl-*
  24.     dc.w    testb-*
  25. testl    dc.w    40000    ;stack
  26.     dc.w    0    ;init
  27.     dc.w    49152    ;interrupt
  28. testb    dc.w    32768
  29.     dc.w    1
  30.     dc.w    testc1-*
  31.     dc.w    49152
  32.     dc.w    9
  33.     dc.w    testc2-*
  34.     dc.w    0
  35. testc2    dc.b    62,0        ;ld a,0
  36.     dc.b    61        ;dec a
  37.     dc.b    50,1,$c0    ;ld ($c001),a
  38.     dc.b    211,254        ;out (254),a
  39. testc1    dc.b    $ed,0,201        ;bug,rts
  40.     even
  41.     endc
  42.  
  43. **** Include stuff ****
  44.  
  45.     incdir    Include40/
  46.     include    exec/exec_lib.i
  47.     include    exec/execbase.i
  48.     include    exec/memory.i
  49.     include    dos/dos_lib.i
  50.     include    dos/dos.i
  51.     include    dos/var.i
  52.     include    dos/dostags.i
  53.     include    misc/AYPlayer.i
  54.     include    misc/z80.i
  55.     include    misc/mine.i
  56.     incdir    ''
  57.  
  58. ***** How single EMUL_Song looks like ******
  59.  
  60.     STRUCTURE    EMUL_Song,0
  61.     UBYTE    ems_assignA    ;0-3 specifies, what amiga channel will be
  62.     UBYTE    ems_assignB    ;assigned to each ay channel (A-C, noise)
  63.     UBYTE    ems_assignC
  64.     UBYTE    ems_assignN
  65.     UWORD    ems_songlen    ;how long the song is in VBIs
  66.     UWORD    ems_fadelen    ;how many VBIs to fade
  67.     UWORD    ems_initnumber    ;this will be stored to HL,DE,BC,IX,IY,A (MSB)
  68.                 ;and all ' registers before calling ems_init
  69.     RPTR    ems_launch    ;Allows same Launch with different initnumbers
  70.     RPTR    ems_firstblock    ;which block(s) install to z80 RAM.
  71.     LABEL    ems_sizeof
  72.  
  73.     STRUCTURE EMUL_Launch,0
  74.     UWORD    eml_stack    ;what will be loaded into SP register
  75.     UWORD    eml_init    ;Routine which set ups the player.
  76.                 ;if zero, use ems_firstblock->emd_address
  77.                 ;or use $1b just for calling ret instruction
  78.     UWORD    eml_interrupt    ;to what address jump to do one VBI play
  79.                 ;if zero, (I*$100+$FF) will be used
  80.     LABEL    eml_sizeof
  81.  
  82.     STRUCTURE EMUL_Block,0
  83.     UWORD    emd_address    ;or null for last block in table
  84.     UWORD    emd_length    ;simply said: take block at emd_binary
  85.     RPTR    emd_binary    ;emd_length bytes long and install it in Z80
  86.     LABEL    emd_sizeof    ;RAM at emd_address
  87.  
  88. **** Real start **********
  89.  
  90. dd    AYPLAYERHEADER    EMUL
  91.     dc.b    0        ;no transpose + terminator for GetVar
  92. AYbase    ds.l    1        ;where ay registers should be "outed"
  93. AYass    ds.l    1        ;where ay channel assignment should be copied
  94. AYfreq    ds.l    1        ;we ignore this anyway
  95.     dc.w    initplayer-*
  96.     dc.w    endplayer-*
  97.     dc.w    initsound-*
  98.     dc.w    endsound-*
  99.     dc.w    interrupt-*
  100.     dc.w    0,0        ;no patterns
  101. name    dc.b    'Z80 Emul Player 1.0',0
  102.     dc.b    'Unknown - original Z80 code is running',0
  103.     dc.b    '(C) 1994 Patrik Rak - Raxoft',0
  104.  
  105. dosn    dc.b    'dos.library',0
  106.     even
  107.  
  108. ;Allocate memory for RAM and Emulator, and install both. Report failure
  109. ;in d0 (0=OK)
  110.  
  111. initplayer
  112.  
  113.     exec    a6
  114.     lea    b(pc),a5
  115.     moveq    #37,d0
  116.     lea    dosn(pc),a1
  117.     jsrlib    OpenLibrary
  118.     move.l    d0,dosb-b(a5)
  119.     beq.b    endplayer
  120.  
  121.     moveq    #-8,d4    ;8 byte pod romkou jako rezerva na stack
  122.     swap    d4    ;jeden staci, ale nejaky potize s allocabs...
  123.     move.l    #zxsize,d2
  124.     bsr.w    Alloc64k
  125.     beq.b    endplayer
  126.     addq.l    #8,d0
  127.     move.l    d0,zxbase-b(a5)
  128.  
  129.     moveq    #0,d4
  130.     move.l    #emullen,d2
  131.     bsr.w    Alloc64k
  132.     beq.b    endplayer
  133.     move.l    d0,emulbase-b(a5)
  134.  
  135.     move.l    d0,a4
  136.     move.l    d0,a1
  137.     lea    emulator(pc),a0
  138.     move.l    #emullen,d0
  139.     jsrlib    CopyMem
  140.     jsrlib    CacheClearU        ;Flush the Caches
  141.  
  142.     btst    #AFB_68010,AttnFlags+1(a6)
  143.     beq.b    .keepmovesrdx
  144.     jsr    z80_MODE68010(a4)
  145.     jsrlib    CacheClearU        ;flush caches
  146. .keepmovesrdx
  147.     lea    z80_out(a4),a1
  148.     lea    out(pc),a0
  149.     move.l    a0,(a1)+    ;out
  150.     lea    return(pc),a0
  151.     move.l    a0,(a1)+    ;in
  152.     move.l    a0,(a1)+    ;ldir delay
  153.     move.l    a0,(a1)        ;lddr delay
  154.  
  155.     moveq    #0,d0
  156. return    rts
  157.  
  158. ;Free the memory.
  159.  
  160. endplayer
  161.     exec    a6
  162.     lea    b(pc),a5
  163.  
  164.     move.l    zxbase(pc),d0
  165.     beq.b    .nozx
  166.     subq.l    #8,d0
  167.     move.l    d0,a1
  168.     move.l    #zxsize,d0
  169.     jsrlib    FreeMem
  170.     clr.l    zxbase-b(a5)
  171. .nozx
  172.     move.l    emulbase(pc),d0
  173.     beq.b    .noz80
  174.     move.l    d0,a1
  175.     move.l    #emullen,d0
  176.     jsrlib    FreeMem
  177.     clr.l    emulbase-b(a5)
  178. .noz80
  179.     move.l    dosb(pc),d0
  180.     beq.b    .nodos
  181.     move.l    d0,a1
  182.     jsrlib    CloseLibrary
  183.     clr.l    dosb-b(a5)
  184. .nodos    moveq    #-1,d0
  185.     rts
  186.  
  187. ;Install channel asignement
  188. ;Install data to the RAM
  189. ;then run the emulator
  190.  
  191. initsound
  192.     exec    a6
  193.     lea    b(pc),a5
  194.  
  195.     move.l    AYass,a1
  196.     move.l    (a0)+,(a1)    ;assignement
  197.     
  198.     move.l    (a0)+,(a5)+    ;songlen+fadelen
  199.     
  200.     clr.l    (a5)+    ;ay_selected(2)+ay_regs(14)=16 bytes
  201.     clr.l    (a5)+
  202.     clr.l    (a5)+
  203.     clr.l    (a5)+
  204.  
  205.     move.l    (a5),a1        ;zxbase
  206.     moveq    #-1,d1
  207.     move.w    #$4000/4-1,d0    ;fill rom with 255
  208. .rom    move.l    d1,(a1)+
  209.     dbra    d0,.rom
  210.     moveq    #0,d1
  211.     move.w    #$c000/4-1,d0    ;fill ram with 0
  212. .ram    move.l    d1,(a1)+
  213.     dbra    d0,.ram
  214.     move.b    #243,(a1)    ;di
  215.     
  216.     move.l    (a5)+,a3    ;zxbase
  217.     move.l    (a5)+,a4    ;emulbase
  218.     move.l    (a0),d1        ;ems_initnumber<<16!ems_initnumber
  219.     move.w    (a0)+,d1
  220.     move.l    a0,a1        ;launch
  221.     add.w    (a0)+,a1
  222.     move.l    a0,a2        ;block
  223.     add.w    (a0),a2
  224.  
  225.     lea    z80_pc(a4),a0
  226.     clr.w    (a0)+        ;reset pc to zero
  227.     move.w    (a1)+,(a0)+    ;set sp to eml_stack
  228.     move.l    d1,(a0)+    ;af,af'
  229.     move.l    d1,(a0)+    ;bc,bc' to ems_initnumber
  230.     move.l    d1,(a0)        ;ix,iy
  231.     move.l    d1,z80_d(a4)    ;de,hl
  232.     move.l    d1,z80_d_(a4)    ;de',hl'
  233.  
  234.     move.b    #$cd,(a3)+    ;call        install z80 startup code
  235.     move.w    (a1)+,d0    ;eml_init
  236.     bne.b    .useit
  237.     move.w    (a2),d0        ;emb_address
  238. .useit
  239.     move.b    d0,(a3)+    ;lsb
  240.     move.w    d0,(a3)+    ;msb
  241.     move.b    #$21,-1(a3)    ;ld    hl,
  242.     move.b    1(a1),(a3)+    ;eml_interrupt lsb
  243.     move.b    (a1),(a3)+    ;msb
  244.     moveq    #z80launchlen-1,d0
  245. .launch    move.b    (a5)+,(a3)+
  246.     dbra    d0,.launch
  247.     
  248. .copy    move.l    a3,d1        ;zxbase+something
  249.     move.w    (a2)+,d1    ;emb_address
  250.     beq.b    .copydone
  251.     move.l    d1,a1        ;zxbase+emb_address
  252.     moveq    #0,d0
  253.     move.w    (a2)+,d0
  254.     move.l    a2,a0
  255.     add.w    (a2)+,a0
  256.     add.w    d1,d0        ;if address+len > 65536
  257.     bcc.b    .ok
  258.     moveq    #0,d0        ;protect the innocent
  259. .ok    sub.w    d1,d0
  260.     jsrlib    CopyMem
  261.     bra.b    .copy
  262. .copydone
  263.     jsrlib    Forbid        ;before starting the process
  264.     move.l    (a5)+,a6    ;dosbase
  265.     lea    var(pc),a0
  266.     move.l    a0,d1
  267.     lea    priority(pc),a0
  268.     move.b    #127,(a0)    ;set pri to maximum
  269.     move.l    a0,d2
  270.     moveq    #2,d3        ;because of bug in V37 (nullterm)
  271.     move.l    #GVF_BINARY_VAR,d4
  272.     jsrlib    GetVar
  273.     lea    processtags(pc),a0
  274.     move.l    a0,d1
  275.     jsrlib    CreateNewProc
  276.     move.l    d0,(a5)        ;process
  277.     exec    a6
  278.     jmplib    Permit        ;now let process do what it wants...
  279.     
  280. ;stop the emulator
  281.  
  282. endsound
  283.     exec    a6
  284.     move.l    process(pc),d0
  285.     beq.b    .none
  286.     move.l    d0,a1
  287.     jsrlib    RemTask
  288.     clr.l    process
  289. .none    rts
  290.  
  291. ;Copy AY registers to AY, then signal Interrupt received to the emulator.
  292. ;(Freqs multiplied by 8).
  293. ;Return fadelen or 0 in d0.
  294.  
  295. interrupt
  296.     exec    a6
  297.     lea    ay_regs(pc),a0
  298.     move.l    AYbase(pc),a1
  299.     moveq    #3-1,d1
  300. .freqs    move.w    (a0)+,d0
  301.     ror.w    #8-3,d0        ;swap bytes & multiple word by 8
  302.     move.w    d0,(a1)+    ;copy first six bytes
  303.     dbra    d1,.freqs
  304.     move.l    (a0)+,(a1)+    ;+4
  305.     move.l    (a0),(a1)    ;+4 = 14 registers
  306.  
  307.     move.l    process(pc),d0    ;if no process exit
  308.     beq.b    .exit
  309.     move.l    d0,a1
  310.     move.l    #SIGBREAKF_CTRL_C,d0
  311.     jsrlib    Signal
  312.     lea    songlen(pc),a0
  313.     moveq    #0,d0
  314.     tst.w    (a0)
  315.     beq.b    .exit
  316.     subq.w    #1,(a0)+
  317.     bne.b    .exit
  318.     move.w    (a0),d0
  319. .exit    rts
  320.  
  321. ************************* Support routines *********************
  322.  
  323. Alloc64k    moveq    #MEMF_FAST!MEMF_PUBLIC,d3
  324.     bsr.b    .main
  325.     bne.b    .exit
  326.     moveq    #MEMF_CHIP!MEMF_PUBLIC,d3
  327.  
  328. ;d2 size, d3 type of mem, d4 word allignment (eg. -1 will allocate $xxxxffff)
  329. ;            in upper word
  330.  
  331.  
  332. .main    lea    MemList(a6),a2
  333. .loop    move.l    (a2),a2
  334.     move.l    (a2),d0
  335.     beq.b    .exit
  336.     move    MH_ATTRIBUTES(a2),d0
  337.     and    d3,d0
  338.     cmp    d3,d0
  339.     bne.b    .loop
  340.     move.l    d4,d0
  341.     move.w    MH_LOWER(a2),d0
  342.     bra.b    .in
  343. .loop2    swap    d0
  344.     addq    #1,d0
  345. .in    swap    d0
  346.     cmp.l    MH_UPPER(a2),d0
  347.     bcc.b    .loop
  348.     move.l    d0,a1
  349.     push    d0
  350.     move.l    d2,d0
  351.     jsrlib    AllocAbs
  352.     tst.l    d0
  353.     popm    d0
  354.     beq.b    .loop2
  355. .exit    rts
  356.  
  357. ****************************** Z80 out routine ***********************
  358.  
  359. out    
  360.     ifne    COLOROUT
  361.     btst    #0,d1
  362.     bne.b    .nofe
  363.     and    #7,d0
  364.     add.w    d0,d0
  365.     lea    .tab(pc,d0.w),a0
  366.     move.w    (a0),$dff180
  367.     rts
  368. .tab    dc.w    $000
  369.     dc.w    $00f
  370.     dc.w    $f00
  371.     dc.w    $f0f
  372.     dc.w    $0f0
  373.     dc.w    $0ff
  374.     dc.w    $ff0
  375.     dc.w    $fff
  376.     endc
  377. .nofe    
  378.     cmp.w    #$fffd,d1
  379.     bne.b    .notselect
  380.     cmp.b    #14,d0
  381.     bcc.b    .exit
  382.     move.b    d0,ay_selected+1
  383.     rts
  384. .notselect
  385.     cmp.w    #$bffd,d1
  386.     bne.b    .exit
  387.     lea    ay_regs(pc),a0
  388.     add.w    ay_selected,a0
  389.     move.b    d0,(a0)
  390. .exit    
  391. nochance    rts
  392.  
  393. ************************** variables ************************
  394.  
  395. ;warning - do not change the order of variables!!! used in initsound!
  396.  
  397. b
  398. songlen    dc.w    0
  399. fadelen    dc.w    0
  400.  
  401. ay_selected    dc.w    0    ;to which ay register we are going to "out"
  402.  
  403. ay_regs    dc.w    0,0,0    ;freqs
  404.     dc.b    0    ;strobe
  405.     dc.b    0    ;noise
  406.     dc.b    0,0,0    ;volumes
  407.     dc.b    0    ;envtype
  408.     dc.b    0,0    ;envfreq
  409.  
  410. zxbase    dc.l    0
  411. emulbase    dc.l    0
  412.  
  413. *************************** Z80 launch code ***********************
  414.  
  415. z80launch
  416. ;    dc.b    $cd    ;call    xx
  417. ;init    dc.b    0,0
  418. ;    dc.b    $21    ;ld    hl,xx
  419. ;rupt    dc.b    0,0
  420.     dc.b    $7c    ;ld    a,h
  421.     dc.b    $b5    ;or    l
  422.     dc.b    $20,$08    ;jr    nz,ok
  423.     dc.b    $ed,$57    ;ld    a,i
  424.     dc.b    $67    ;ld    h,a
  425.     dc.b    $2d    ;dec    l
  426.     dc.b    $5e    ;ld    e,(hl)
  427.     dc.b    $23    ;inc    hl
  428.     dc.b    $56    ;ld    d,(hl)
  429.     dc.b    $eb    ;ex    de,hl
  430.     dc.b    $22,$17,0;ok ld    (here+1),hl
  431.     dc.b    $76    ;loop    halt
  432.     dc.b    $cd,0,0    ;here    call    xx
  433.     dc.b    $18,$fa    ;jr    loop
  434.     dc.b    201    ;ret
  435. z80launchlen    equ    *-z80launch
  436.  
  437. ********************* Process Data  *********************
  438.  
  439. dosb    dc.l    0
  440. process    dc.l    0
  441.     dc.b    'RAM:'
  442. var    dc.b    'Z80debug',0
  443. format    dc.b    'Error: %08lx Emulator: %08lx RAM: %08lx',10,10
  444.     dc.b    'PC:%04x SP :%04x',10
  445.     dc.b    'AF:%04x AF'':%04x',10
  446.     dc.b    'BC:%04x BC'':%04x',10
  447.     dc.b    'DE:%04x DE'':%04x',10
  448.     dc.b    'HL:%04x HL'':%04x',10
  449.     dc.b    'IX:%04x IY :%04x',10
  450.     dc.b    'I :  %02x R  :  %02x',10
  451.     dc.b    0
  452.  
  453. processtags
  454.     dc.l    NP_Entry,entry
  455.     dc.l    NP_Name,name
  456.     dc.l    NP_Priority
  457.     dc.b    0,0,0
  458. priority dc.b    127            ;must be before TAG_DONE!!!
  459.     dc.l    TAG_DONE        ;Because of nullterm bug in v37 GetVar
  460.  
  461. entry    lea    zxbase(pc),a0
  462.     move.l    (a0)+,d7        ;zxbase
  463.     move.l    (a0),a0            ;emulbase
  464.     jsr    z80_RUN(a0)
  465.     exec    a6            ;hopefully, this never gets executed
  466.     jsrlib    Forbid            ;no one can break us now
  467.     lea    dosb(pc),a0
  468.     move.l    (a0)+,a6        ;dosbase
  469.     clr.l    (a0)+            ;process (no one will try RemTask() now)
  470.     move.l    a0,d1            ;debugname
  471.     move.l    #MODE_NEWFILE,d2
  472.     jsrlib    Open
  473.     move.l    d0,d6
  474.     beq.b    .exit        ;nochance
  475.     move.l    emulbase(pc),a5
  476.     move.l    a7,a2
  477.     lea    z80_i(a5),a4
  478.     move.l    (a4),d0
  479.     lsr.l    #8,d0
  480.     and.w    #$ff,d0
  481.     push    d0        ;r,i
  482.     move.l    -(a4),-(sp)    ;ix,iy
  483.     lea    z80_which(a5),a3
  484.     add.w    (a3),a3        ;correct exx set
  485.     move.w    2(a3),d0    ;other set
  486.     move.w    (a3,d0),-(sp)    ;hl'
  487.     move.w    (a3),-(sp)    ;hl
  488.     move.w    -2(a3,d0),-(sp)    ;de'
  489.     move.w    -(a3),-(sp)    ;de
  490.     move.l    -(a4),-(sp)    ;bc,bc'
  491.     move.l    -(a4),-(sp)    ;af,af'
  492.     move.l    -(a4),-(sp)    ;pc,sp'
  493.     lea    zxbase(pc),a0
  494.     push    (a0)+        ;zxbase
  495.     push    (a0)        ;emulbase
  496.     push    d7        ;return code from emulator
  497.     lea    format(pc),a0
  498.     move.l    d6,d1
  499.     move.l    a0,d2
  500.     move.l    a7,d3
  501.     jsrlib    VFPrintf
  502.     move.l    a2,a7
  503.     move.l    d6,d1
  504.     jsrlib    Close
  505. .exit    rts
  506.     
  507. *********************** z80 emulator *************************
  508.  
  509. emulator    incbin    'asm:sources/fxs/Z80'    ;sorry, not distributed :-)
  510. emullen    equ    *-emulator
  511. zxsize    equ    8+65536+8
  512.  
  513.